package com.yricky.astral.project

object Hazuki {
    /**
     * @see HazukiStandard.check
     */
    object CheckLevel{
        const val ignore = -1
        const val allow   = 0
        const val confirm = 1
        const val forbid  = 2
    }

    object Rules{
        const val WidthTooLarge = "Width is bigger than 64."
        const val AssignToConstValue = "Signal assign to a const value."
        const val WidthMismatch = "Width of signal mismatch."
        const val SelectionMissElseBranch = "Selection miss else branch."
    }

    interface Checkable{
        val standard:HazukiStandard
    }

    /**
     * @see IgnoreAll
     * @see AllowAll
     * @see ConfirmAll
     * @see ForbidAll
     */
    abstract class HazukiStandard{
        /**
         * @param rule defined in [Hazuki.Rules]
         */
        protected open fun maskCheck(rule:String,scene:String,checkLevel:Int):Int = checkLevel

        /**
         * @param rule defined in [Hazuki.Rules]
         */
        fun check(rule:String,scene:String,checkLevel:Int = CheckLevel.forbid){
            when(maskCheck(rule, scene, checkLevel)){
                CheckLevel.ignore ->return
                CheckLevel.allow -> println("Hazuki:allow  | $rule Scene:$scene")
                CheckLevel.confirm -> {
                    println("Hazuki:confirm| $rule Scene:$scene\nDo you want to continue?(y/N)")
                    if(readLine()?.trim() == "y") return else {
                        println("Abort!")
                        Runtime.getRuntime().exit(-1)
                    }
                }
                CheckLevel.forbid -> throw RuntimeException("\nHazuki:forbid | $rule Scene:$scene")
            }
        }
    }



    object DefaultStandard:HazukiStandard()

    object IgnoreAll:HazukiStandard(){
        override fun maskCheck(rule: String, scene: String, checkLevel: Int):Int = CheckLevel.ignore
    }

    object AllowAll:HazukiStandard(){
        override fun maskCheck(rule: String, scene: String, checkLevel: Int):Int = CheckLevel.allow
    }

    object ConfirmAll:HazukiStandard(){
        override fun maskCheck(rule: String, scene: String, checkLevel: Int):Int = CheckLevel.confirm
    }

    object ForbidAll:HazukiStandard(){
        override fun maskCheck(rule: String, scene: String, checkLevel: Int):Int = CheckLevel.forbid
    }
}